home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / New System Software Extensions / OpenDoc A6 / OpenDoc Parts Framework / OPF / Examples / Draw / Sources / Shapes.cpp < prev    next >
Encoding:
Text File  |  1994-04-21  |  43.6 KB  |  1,654 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Shapes.cpp
  4. //    Release Version:    $ 1.0d1 $
  5. //
  6. //    Author:                Henri Lamiraux
  7. //    Creation Date:        3/28/94
  8. //
  9. //    Copyright:    © 1993, 1994 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //========================================================================================
  12.  
  13. #ifndef SHAPES_H
  14. #include "Shapes.h"
  15. #endif
  16.  
  17. #ifndef UTILITIES_H
  18. #include "Utilities.h"
  19. #endif
  20.  
  21. #ifndef DRAWPART_H
  22. #include "DrawPart.h"
  23. #endif
  24.  
  25. #ifndef DRAWSELECTION_H
  26. #include "DrawSelection.h"
  27. #endif
  28.  
  29. // ----- Framework Includes -----
  30. #ifndef FWPROXY_H
  31. #include "FWProxy.h"
  32. #endif
  33.  
  34. #ifndef FWBORDER_H
  35. #include "FWBorder.h"
  36. #endif
  37.  
  38. #ifndef FWFRMING_H
  39. #include "FWFrming.h"
  40. #endif
  41.  
  42. #ifndef FWUTIL_H
  43. #include "FWUtil.h"
  44. #endif
  45.  
  46. #ifndef FWPART_H
  47. #include "FWPart.h"
  48. #endif
  49.  
  50. #ifndef FWFACET_H
  51. #include "FWFacet.h"
  52. #endif
  53.  
  54. #ifndef FWSELECT_H
  55. #include "FWSelect.h"
  56. #endif
  57.  
  58. // ----- Graphic Includes -----
  59.  
  60. #ifndef FWRECT_H
  61. #include "FWRect.h"
  62. #endif
  63.  
  64. #ifndef FWSHAPE_H
  65. #include "FWShape.h"
  66. #endif
  67.  
  68. #ifndef FWSTYLE_H
  69. #include "FWStyle.h"
  70. #endif
  71.  
  72. #ifndef FWINK_H
  73. #include "FWInk.h"
  74. #endif
  75.  
  76. #ifndef FWGCONST_H
  77. #include "FWGConst.h"
  78. #endif
  79.  
  80. #ifndef FWLINSHP_H
  81. #include "FWLinShp.h"
  82. #endif
  83.  
  84. #ifndef FWRECSHP_H
  85. #include "FWRecShp.h"
  86. #endif
  87.  
  88. #ifndef FWRRCSHP_H
  89. #include "FWRRcShp.h"
  90. #endif
  91.  
  92. #ifndef FWOVLSHP_H
  93. #include "FWOvlShp.h"
  94. #endif
  95.  
  96. #ifndef FWSUSTRM_H
  97. #include "FWSUStrm.h"
  98. #endif
  99.  
  100. // ----- OpenDoc Includes
  101.  
  102. #ifndef _WINDOW_
  103. #include <Window.h>
  104. #endif
  105.  
  106. #ifndef _TRNSFORM_
  107. #include <Trnsform.h>
  108. #endif
  109.  
  110. #ifndef _SHAPE_
  111. #include <Shape.h>
  112. #endif
  113.  
  114. #ifndef _FRAME_
  115. #include <Frame.h>
  116. #endif
  117.  
  118. #ifndef _FACET_
  119. #include <Facet.h>
  120. #endif
  121.  
  122. #ifndef _DRAFT_
  123. #include <Draft.h>
  124. #endif
  125.  
  126. // ----- Macintosh Includes -----
  127.  
  128. #ifndef __QUICKDRAW__
  129. #include <Quickdraw.h>
  130. #endif
  131.  
  132. #ifndef __DRAG__
  133. #include <Drag.h>
  134. #endif
  135.  
  136. #ifndef __TOOLUTILS__
  137. #include <ToolUtils.h>
  138. #endif
  139.  
  140. #ifndef mathRoutinesIncludes
  141. #include <math routines.h>                // for ff()
  142. #endif
  143.  
  144. #pragma segment drawpart
  145.  
  146. //==============================================================================
  147. // class CBaseShape
  148. //==============================================================================
  149.  
  150. //-------------------------------------------------------------------------
  151. // CBaseShape::CBaseShape
  152. //-------------------------------------------------------------------------
  153.  
  154. CBaseShape::CBaseShape(short numberOfHandles, unsigned short shapeType) :
  155.     fSelected(FALSE),
  156.     fClipShape(NULL),
  157.     fNumberOfHandles(numberOfHandles),
  158.     fShapeType(shapeType),
  159.     fPublishLink(NULL),
  160.     fSubscribLink(NULL),
  161.     fFrameFill(kFrameOnly),
  162.     fPenInk(FW_kRGBBlack, FW_kRGBWhite, FW_kCopy),
  163.     fBrushInk(FW_kRGBBlack, FW_kRGBWhite, FW_kCopy),
  164.     fPenStyle(ff(1)),
  165.     fBrushStyle(ff(1))
  166. {
  167. }
  168.  
  169. //-------------------------------------------------------------------------
  170. // CBaseShape::~CBaseShape
  171. //-------------------------------------------------------------------------
  172.  
  173. CBaseShape::~CBaseShape()
  174. {
  175.     delete fPublishLink;
  176.     delete fSubscribLink;
  177.     
  178.     delete fClipShape;
  179. }
  180.  
  181. //-------------------------------------------------------------------------
  182. // CBaseShape::Removed
  183. //-------------------------------------------------------------------------
  184.  
  185. void CBaseShape::Removed()
  186. {
  187. }
  188.  
  189. //-------------------------------------------------------------------------
  190. // CBaseShape::Track
  191. //-------------------------------------------------------------------------
  192.  
  193. FW_Boolean CBaseShape::Track(FW_CGraphicContext* gc, FW_CStyle trackStyle, const FW_CPoint& anchorPoint, XMPEventData event)
  194. {
  195.     if (!::WaitMouseMoved(event->where))
  196.         return FALSE;
  197.     
  198.     FW_CInk trackInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  199.     SetShapeProperties(FW_kFramed, trackInk, trackStyle);
  200.     
  201.     FW_CPoint currentLoc;
  202.     FW_CPoint prevLoc = anchorPoint;
  203.     
  204.     FW_Boolean stillDown = TRUE;
  205.     FW_Boolean erase = FALSE;
  206.     
  207.     while (stillDown)
  208.     {
  209.         FW_SPlatformPoint qdLoc;
  210.         ::GetMouse(&qdLoc);
  211.         currentLoc = qdLoc;
  212.         
  213.         // ----- Adjust for the size of the cursor
  214.         if (anchorPoint.x < currentLoc.x)
  215.             currentLoc.x += ff(1);
  216.         if (anchorPoint.y < currentLoc.y)
  217.             currentLoc.y += ff(1);
  218.         
  219.         // ----- Test if moved    
  220.         if (prevLoc != currentLoc)
  221.         {
  222.             if (erase)
  223.                 TrackFeedback(gc, anchorPoint, prevLoc, TRUE);        // erase
  224.             
  225.             TrackFeedback(gc, anchorPoint, currentLoc, FALSE);        // draw
  226.             
  227.             WaitForTick();
  228.             
  229.             prevLoc = currentLoc;
  230.             erase = TRUE;
  231.         }
  232.         
  233.         stillDown = ::StillDown();
  234.     }
  235.     
  236.     if (erase)
  237.         TrackFeedback(gc, anchorPoint, currentLoc, TRUE);    // Erase
  238.         
  239.     ::PenNormal();
  240.     
  241.     return (currentLoc != anchorPoint);
  242. }
  243.  
  244. //-------------------------------------------------------------------------
  245. // CBaseShape::TrackFeedback
  246. //-------------------------------------------------------------------------
  247.  
  248. void CBaseShape::TrackFeedback(FW_CGraphicContext* gc,
  249.                                 const FW_CPoint& anchorPoint, 
  250.                                 const FW_CPoint& currentPoint, 
  251.                                 FW_Boolean erase)
  252. {
  253.     if (!erase)
  254.         SetShapeGeometry(anchorPoint, currentPoint);
  255.  
  256.     RenderShape(gc);
  257. }
  258.  
  259. //-------------------------------------------------------------------------
  260. // CBaseShape::SelectShape
  261. //-------------------------------------------------------------------------
  262.  
  263. void CBaseShape::SelectShape(FW_Boolean state)
  264. {
  265.     fSelected = state;
  266. }
  267.  
  268. //-------------------------------------------------------------------------
  269. // CBaseShape::ClearCache
  270. //-------------------------------------------------------------------------
  271.  
  272. void CBaseShape::ClearCache()
  273. {
  274.     delete fClipShape;
  275.     fClipShape = NULL;
  276. }
  277.  
  278. //-------------------------------------------------------------------------
  279. // CBaseShape::DrawShapeHandles
  280. //-------------------------------------------------------------------------
  281.  
  282. void CBaseShape::DrawShapeHandles(FW_CFacet* facet, FW_Boolean /*turOn*/)
  283. {    
  284. FW_UNUSED(facet);
  285.  
  286.     for (short i=1; i<=fNumberOfHandles; i++)
  287.     {
  288.         DrawHandle(i);
  289.     }
  290. }
  291.  
  292. //-------------------------------------------------------------------------
  293. // CBaseShape::WhichHandle
  294. //-------------------------------------------------------------------------
  295.  
  296. short CBaseShape::WhichHandle(FW_CFacet* facet, const FW_CPoint& mouse) const
  297. {
  298. FW_UNUSED(facet);
  299.  
  300.     FW_CRect handleRect;
  301.     
  302.     for (short i=1; i<=fNumberOfHandles; i++)
  303.     {
  304.         CalcHandleRect(i, &handleRect);
  305.         if (handleRect.Contains(mouse))
  306.             return i;
  307.     }
  308.         
  309.     return 0;
  310. }
  311.  
  312. //-------------------------------------------------------------------------
  313. // CBaseShape::CalcHandleRect
  314. //-------------------------------------------------------------------------
  315.  
  316. void CBaseShape::CalcHandleRect(short whichHandle, FW_CRect* handleRect) const
  317. {
  318.     FW_CPoint pt;
  319.     GetHandleCenter(whichHandle, &pt);
  320.     handleRect->Set(pt.x - ff(2), pt.y - ff(2), pt.x + ff(3), pt.y + ff(3));
  321. }
  322.  
  323. //-------------------------------------------------------------------------
  324. // CBaseShape::DrawHandle
  325. //-------------------------------------------------------------------------
  326.  
  327. void CBaseShape::DrawHandle(short whichHandle)
  328. {
  329.     FW_CRect handleRect;
  330.     CalcHandleRect(whichHandle, &handleRect);
  331.     FW_SPlatformRect qdRect = handleRect;
  332.     ::InvertRect(&qdRect);
  333. }
  334.  
  335. //-------------------------------------------------------------------------
  336. // CBaseShape::SetFrameFillStyle
  337. //-------------------------------------------------------------------------
  338.  
  339. void CBaseShape::SetFrameFillStyle(unsigned short style)
  340. {
  341.     ClearCache();
  342.     fFrameFill = style;
  343. }
  344.  
  345. //-------------------------------------------------------------------------
  346. // CBaseShape::SetPenStyle
  347. //-------------------------------------------------------------------------
  348.  
  349. void CBaseShape::SetPenStyle(FW_CStyle penStyle)
  350. {
  351.     ClearCache();
  352.     fPenStyle = penStyle;
  353. }
  354.  
  355. //-------------------------------------------------------------------------
  356. // CBaseShape::InSelectionRect
  357. //-------------------------------------------------------------------------
  358.  
  359. FW_Boolean CBaseShape::InSelectionRect(const FW_CRect& selectRect) const
  360. {
  361.     FW_CRect bounds = GetBoundingBox();
  362.     
  363.     return bounds == bounds.Intersects(selectRect);
  364. }
  365.  
  366. //-------------------------------------------------------------------------
  367. // CBaseShape::Flatten
  368. //-------------------------------------------------------------------------
  369.  
  370. void CBaseShape::Flatten(XMPStorageUnit* storage)
  371. {    
  372.     storage->SetValue(sizeof(fShapeType), (XMPValue)&fShapeType);
  373.     storage->SetValue(sizeof(fSelected), (XMPValue)&fSelected);
  374.     storage->SetValue(sizeof(fNumberOfHandles), (XMPValue)&fNumberOfHandles);
  375.  
  376.     FW_CStorageUnitSink sink(storage);
  377.     FW_CWritableStream stream(&sink);
  378.     
  379.     fPenInk->Flatten(stream);
  380.     fBrushInk->Flatten(stream);
  381.     fPenStyle->Flatten(stream);
  382.     fBrushStyle->Flatten(stream);
  383.  
  384.     storage->SetValue(sizeof(fFrameFill), (XMPValue)&fFrameFill);    
  385. }
  386.  
  387. //-------------------------------------------------------------------------
  388. // CBaseShape::Unflatten
  389. //-------------------------------------------------------------------------
  390.  
  391. void CBaseShape::Unflatten(CDrawPart* drawPart, XMPStorageUnit* storage)
  392. {    
  393. FW_UNUSED(drawPart);
  394.  
  395. //    We don't Unflatten the shape type because it was already read
  396. //    storage->GetValue(sizeof(fShapeType), (XMPValue)&fShapeType);
  397.     storage->GetValue(sizeof(fSelected), (XMPValue)&fSelected);
  398.     storage->GetValue(sizeof(fNumberOfHandles), (XMPValue)&fNumberOfHandles);
  399.     
  400.     FW_CStorageUnitSink sink(storage);
  401.     FW_CReadableStream stream(&sink);
  402.     
  403.     fPenInk->Unflatten(stream);
  404.     fBrushInk->Unflatten(stream);
  405.     fPenStyle->Unflatten(stream);
  406.     fBrushStyle->Unflatten(stream);
  407.  
  408.     storage->GetValue(sizeof(fFrameFill), (XMPValue)&fFrameFill);    
  409. }
  410.  
  411. //-------------------------------------------------------------------------
  412. // CBaseShape::CloneTo
  413. //-------------------------------------------------------------------------
  414.  
  415. void CBaseShape::CloneTo(XMPStorageUnit* storageUnit, FW_CFrame* commandFrame, XMPCloneKind cloneKind)
  416. {    
  417. FW_UNUSED(commandFrame);
  418. FW_UNUSED(cloneKind);
  419.  
  420.     Flatten(storageUnit);
  421. }
  422.  
  423. //-------------------------------------------------------------------------
  424. // CBaseShape::CloneFrom
  425. //-------------------------------------------------------------------------
  426.  
  427. void CBaseShape::CloneFrom(CDrawPart* drawPart, XMPStorageUnit* storageUnit, XMPCloneKind cloneKind)
  428. {    
  429. FW_UNUSED(cloneKind);
  430.  
  431.     Unflatten(drawPart, storageUnit);
  432. }
  433.  
  434. //-------------------------------------------------------------------------
  435. // CBaseShape::MovedAfter
  436. //-------------------------------------------------------------------------
  437.  
  438. void CBaseShape::MovedAfter(CBaseShape* shape)
  439. {
  440. FW_UNUSED(shape);
  441. }
  442.  
  443. //-------------------------------------------------------------------------
  444. // CBaseShape::MovedBefore
  445. //-------------------------------------------------------------------------
  446.  
  447. void CBaseShape::MovedBefore(CBaseShape* shape)
  448. {
  449. FW_UNUSED(shape);
  450. }
  451.  
  452. //-------------------------------------------------------------------------
  453. // CBaseShape::MovedFirst
  454. //-------------------------------------------------------------------------
  455.  
  456. void CBaseShape::MovedFirst()
  457. {
  458. }
  459.  
  460. //-------------------------------------------------------------------------
  461. // CBaseShape::MovedLast
  462. //-------------------------------------------------------------------------
  463.  
  464. void CBaseShape::MovedLast()
  465. {
  466. }
  467.  
  468. //-------------------------------------------------------------------------
  469. // CBaseShape::SetFrozen
  470. //-------------------------------------------------------------------------
  471.  
  472. FW_Boolean CBaseShape::SetFrozen(FW_Boolean state)
  473. {
  474. FW_UNUSED(state);
  475.     return FALSE;    // Means I don't care
  476. }
  477.  
  478. //-------------------------------------------------------------------------
  479. // CBaseShape::IsFrozen
  480. //-------------------------------------------------------------------------
  481.  
  482. FW_Boolean CBaseShape::IsFrozen() const
  483. {
  484.     return FALSE;
  485. }
  486.  
  487. //-------------------------------------------------------------------------
  488. // CBaseShape::GetPenSize
  489. //-------------------------------------------------------------------------
  490.  
  491. XMPCoordinate CBaseShape::GetPenSize() const
  492. {
  493.     return fBaseShape->GetShapeStyle()->GetPenSize();
  494. }
  495.  
  496. //-------------------------------------------------------------------------
  497. // CBaseShape::SetShapeProperties
  498. //-------------------------------------------------------------------------
  499.  
  500. void CBaseShape::SetShapeProperties(FW_ShapeFills shapeFills, FW_CInk ink, FW_CStyle style)
  501. {
  502.     fBaseShape->SetShapeInk(ink);
  503.     fBaseShape->SetShapeStyle(style);
  504.     fBaseShape->SetShapeFill(shapeFills);
  505. }
  506.  
  507. //-------------------------------------------------------------------------
  508. // CBaseShape::RenderShape
  509. //-------------------------------------------------------------------------
  510.  
  511. void CBaseShape::RenderShape(FW_CGraphicContext* gc)
  512. {
  513.     fBaseShape->Draw(gc);
  514. }
  515.  
  516. //=========================================================================
  517. // class CLineShape
  518. //=========================================================================
  519.  
  520. //-------------------------------------------------------------------------
  521. // CLineShape::CLineShape
  522. //-------------------------------------------------------------------------
  523.  
  524. CLineShape::CLineShape() :
  525.     CBaseShape(2, kLineShape),
  526.     fShape(FW_kZeroPoint, FW_kZeroPoint)
  527. {
  528.     fBaseShape = fShape;
  529. }
  530.  
  531. //-------------------------------------------------------------------------
  532. // CLineShape::~CLineShape
  533. //-------------------------------------------------------------------------
  534.  
  535. CLineShape::~CLineShape()
  536. {
  537. }
  538.  
  539. //-------------------------------------------------------------------------
  540. // CLineShape::DrawShape
  541. //-------------------------------------------------------------------------
  542.  
  543. void CLineShape::DrawShape(FW_CGraphicContext* gc)
  544. {    
  545.     fShape->SetShapeFill(FW_kFramed);
  546.     fShape->SetShapeInk(GetPenInk());
  547.     fShape->SetShapeStyle(GetPenStyle());
  548.     fShape->Draw(gc);
  549.         
  550.     // ----- Remove what I have drawn
  551.     XMPShape* clipShape = ::NewXMPShape();
  552.     gc->GetClipShape(clipShape);
  553.     clipShape->Subtract(GetClipShape(gc));
  554.     gc->SetClipShape(clipShape);
  555.     delete clipShape;
  556. }
  557.  
  558. //-------------------------------------------------------------------------
  559. // CLineShape::OutlineShape
  560. //-------------------------------------------------------------------------
  561.  
  562. void CLineShape::OutlineShape(FW_CGraphicContext* gc, FW_CInk ink, FW_CStyle style, 
  563.                               const FW_CPoint& pt1, const FW_CPoint& pt2)
  564. {
  565.     FW_CLineShape lineShape(pt1, pt2);
  566.     lineShape->SetShapeInk(ink);
  567.     lineShape->SetShapeStyle(style);
  568.     lineShape->SetShapeFill(FW_kFramed);
  569.     lineShape->Draw(gc);
  570. }
  571.  
  572. //-------------------------------------------------------------------------
  573. // CLineShape::HitTest
  574. //-------------------------------------------------------------------------
  575.  
  576. FW_Boolean CLineShape::HitTest(FW_CGraphicContext* gc, const FW_CPoint& mouse, XMPEventData event) const
  577. {
  578. FW_UNUSED(event);
  579. FW_UNUSED(gc);
  580.  
  581.     FW_CRect rect = GetBoundingBox();
  582.     rect.Inset(ff(-2), ff(-2));
  583.     
  584.     FW_CPoint endPoint = GetLineEnd();
  585.     FW_CPoint startPoint = GetLineStart();
  586.     
  587.     FW_Boolean result = FALSE;
  588.     
  589.     if (rect.Contains(mouse))
  590.     {
  591.         XMPCoordinate dx = endPoint.x - startPoint.x;
  592.         XMPCoordinate dy = endPoint.y - startPoint.y;
  593.         
  594.         if (dx == 0)        // vertical line
  595.         {
  596.             if ((endPoint.y <= mouse.y && mouse.y <= startPoint.y) || 
  597.                 (startPoint.y <= mouse.y && mouse.y <= endPoint.y))
  598.             {
  599.                 result = Abs(endPoint.x - mouse.x) < ff(3);
  600.             }
  601.         }
  602.         else if (dy == 0)    // horizontal line
  603.         {
  604.             if ((endPoint.x <= mouse.x && mouse.x <= startPoint.x) || 
  605.                 (startPoint.x <= mouse.x && mouse.x <= endPoint.x))
  606.             {
  607.                 result = Abs(endPoint.y - mouse.y) < ff(3);
  608.             }
  609.         }
  610.         else
  611.         {
  612.             XMPCoordinate a2 = dx * (mouse.y - startPoint.y) - dy * (mouse.x - startPoint.x);
  613.             if (a2<0) a2 *= -1;
  614.             
  615.             if (dx<0) dx *= -1;
  616.             if (dy<0) dy *= -1;
  617.             
  618.             XMPCoordinate v;
  619.             if (dx < dy) v = dx / 2;
  620.             else v = dy / 2;
  621.             
  622.             result = (a2 / (v + dx + dy)) < ff(3);
  623.         }
  624.     }
  625.     
  626.     return result;
  627. }
  628.  
  629. //-------------------------------------------------------------------------
  630. // CLineShape::GetUpdateShape
  631. //-------------------------------------------------------------------------
  632.  
  633. void CLineShape::GetUpdateShape(XMPShape* updateShape) const
  634. {
  635.     FW_CRect rect = GetBoundingBox();
  636.     
  637.     if (IsSelected())
  638.         rect.Inset(ff(-2), ff(-2));
  639.  
  640.     updateShape->SetRectangle(&rect);
  641. }
  642.  
  643. //-------------------------------------------------------------------------
  644. // CLineShape::GetBoundingBox
  645. //-------------------------------------------------------------------------
  646.  
  647. FW_CRect CLineShape::GetBoundingBox() const
  648. {
  649.     return fShape->GetShapeBounds();
  650. }
  651.  
  652. //-------------------------------------------------------------------------
  653. // CLineShape::GetClipShape
  654. //-------------------------------------------------------------------------
  655.  
  656. XMPShape* CLineShape::GetClipShape(FW_CGraphicContext* gc)
  657. {
  658.     if (fClipShape == NULL)
  659.     {
  660.         FW_PlatformRegion rgn = ::NewRgn();
  661.         GetDragRgn(gc, rgn);
  662.         fClipShape = ::NewXMPShape(rgn);
  663.     }
  664.     
  665.     return fClipShape;
  666. }
  667.  
  668. //-------------------------------------------------------------------------
  669. // MakeLineRgn
  670. //-------------------------------------------------------------------------
  671.  
  672. void MakeLineRgn(FW_SPlatformPoint start, const FW_SPlatformPoint end, short pen)
  673. {    
  674.     ::MoveTo(start.h, start.v);
  675.     ::LineTo(end.h, end.v);
  676.     ::Line(pen, 0);
  677.     ::Line(0, pen);
  678.     ::LineTo(start.h + pen, start.v + pen);
  679.     ::Line(-pen, 0);
  680.     ::Line(0, -pen);
  681. }
  682.  
  683. //-------------------------------------------------------------------------
  684. // CLineShape::GetDragRgn
  685. //-------------------------------------------------------------------------
  686.  
  687. void CLineShape::GetDragRgn(FW_CGraphicContext* gc, FW_PlatformRegion dragRgn)
  688. {
  689. FW_UNUSED(gc);
  690.  
  691.     XMPCoordinate penSize = GetPenSize();
  692.     
  693.     FW_CPoint endPoint = GetLineEnd();
  694.     FW_CPoint startPoint = GetLineStart();
  695.     FW_SPlatformPoint start = startPoint;
  696.     FW_SPlatformPoint end = endPoint;
  697.     short pen = FixedToInt(penSize);
  698.  
  699.     ::OpenRgn();
  700.     
  701.     if (endPoint.x < startPoint.x)
  702.     {
  703.         if (endPoint.y < startPoint.y)
  704.         {            
  705.             ::MoveTo(start.h + pen, start.v);
  706.             ::LineTo(end.h + pen, end.v);
  707.             ::Line(-pen, 0);            
  708.             ::Line(0, pen);
  709.             ::LineTo(start.h, start.v + pen);            
  710.             ::Line(-pen, 0);
  711.             ::Line(0, -pen);
  712.         }
  713.         else if (endPoint.y > startPoint.y)
  714.         {
  715.             ::MakeLineRgn(start, end, pen);        
  716.         }
  717.         else
  718.         {
  719.             ::MakeLineRgn(start, end, pen);        
  720.         }
  721.     }
  722.     else if (endPoint.x > startPoint.x)
  723.     {
  724.         if (endPoint.y < startPoint.y)
  725.         {
  726.             ::MakeLineRgn(start, end, pen);        
  727.         }
  728.         else if (endPoint.y > startPoint.y)
  729.         {
  730.             ::MoveTo(start.h, start.v);
  731.             ::Line(pen, 0);
  732.             ::LineTo(end.h + pen, end.v);
  733.             ::Line(0, pen);
  734.             ::Line(-pen, 0);
  735.             ::LineTo(start.h, start.v + pen);
  736.             ::Line(0, -pen);
  737.         }
  738.         else
  739.         {
  740.             ::MakeLineRgn(start, end, pen);        
  741.         }
  742.     }
  743.     else
  744.     {
  745.         if (endPoint.y < startPoint.y)
  746.         {
  747.             ::MakeLineRgn(start, end, pen);        
  748.         }
  749.         else if (endPoint.y > startPoint.y)
  750.         {
  751.             ::MakeLineRgn(start, end, pen);        
  752.         }
  753.         else
  754.         {        
  755.             ::MoveTo(start.h, start.v);
  756.             ::Line(pen, 0);
  757.             ::Line(0, pen);
  758.             ::Line(-pen, 0);
  759.             ::Line(0, -pen);            
  760.         }
  761.     }
  762.     
  763.     ::CloseRgn(dragRgn);
  764. }
  765.  
  766. //-------------------------------------------------------------------------
  767. // CLineShape::GetHandleCenter
  768. //-------------------------------------------------------------------------
  769.  
  770. void CLineShape::GetHandleCenter(short whichHandle, FW_CPoint* center) const
  771. {
  772.     if (whichHandle == 1)
  773.         *center = GetLineStart();
  774.     else
  775.         *center = GetLineEnd();
  776. }
  777.  
  778. //-------------------------------------------------------------------------
  779. // CLineShape::ResizeFeedback
  780. //-------------------------------------------------------------------------
  781.  
  782. void CLineShape::ResizeFeedback(FW_CGraphicContext* gc, FW_CInk ink, FW_CStyle style, const FW_CRect& srcRect, const FW_CRect& dstRect)
  783. {
  784.     FW_CPoint pt1 = GetLineStart();
  785.     FW_CPoint pt2 = GetLineEnd();
  786.  
  787.     pt1.Map(srcRect, dstRect);
  788.     pt2.Map(srcRect, dstRect);
  789.     
  790.     OutlineShape(gc, ink, style, pt1, pt2);
  791. }
  792.  
  793. //-------------------------------------------------------------------------
  794. // CLineShape::MapShape
  795. //-------------------------------------------------------------------------
  796.  
  797. void CLineShape::MapShape(const FW_CRect& srcRect, const FW_CRect& dstRect)
  798. {
  799.     FW_CPoint pt1 = GetLineStart();
  800.     pt1.Map(srcRect, dstRect);
  801.     
  802.     FW_CPoint pt2 = GetLineEnd();
  803.     pt2.Map(srcRect, dstRect);
  804.     
  805.     SetShapeGeometry(pt1, pt2);
  806. }
  807.  
  808. //-------------------------------------------------------------------------
  809. // CLineShape::OffsetShape
  810. //-------------------------------------------------------------------------
  811.  
  812. void CLineShape::OffsetShape(XMPCoordinate xDelta, XMPCoordinate yDelta)
  813. {
  814.     ClearCache();
  815.     
  816.     XMPTransform* t = ::NewXMPTransform(FW_CPoint(xDelta, yDelta));
  817.     fShape->Transform(t);
  818.     delete t;
  819. }
  820.  
  821. //-------------------------------------------------------------------------
  822. // CLineShape::SetShapeGeometry
  823. //-------------------------------------------------------------------------
  824.  
  825. void CLineShape::SetShapeGeometry(const FW_CPoint& anchorPoint,  const FW_CPoint& currentPoint)
  826. {
  827.     ClearCache();
  828.     
  829.     fShape->SetLineStart(anchorPoint);
  830.     fShape->SetLineEnd(currentPoint);
  831. }
  832.  
  833. //-------------------------------------------------------------------------
  834. // CLineShape::Flatten
  835. //-------------------------------------------------------------------------
  836.  
  837. void CLineShape::Flatten(XMPStorageUnit* storage)
  838. {    
  839.     CBaseShape::Flatten(storage);
  840.     
  841.     FW_CPoint p = GetLineStart();
  842.     storage->SetValue(sizeof(p), (XMPValue)&p);
  843.     p = GetLineEnd();
  844.     storage->SetValue(sizeof(p), (XMPValue)&p);
  845. }
  846.  
  847. //-------------------------------------------------------------------------
  848. // CLineShape::Unflatten
  849. //-------------------------------------------------------------------------
  850.  
  851. void CLineShape::Unflatten(CDrawPart* drawPart, XMPStorageUnit* storage)
  852. {    
  853.     CBaseShape::Unflatten(drawPart, storage);
  854.     
  855.     FW_CPoint pt1, pt2;
  856.     storage->GetValue(sizeof(pt1), (XMPValue)&pt1);
  857.     storage->GetValue(sizeof(pt2), (XMPValue)&pt2);
  858.     
  859.     SetShapeGeometry(pt1, pt2);
  860. }
  861.  
  862. //==============================================================================
  863. // class CBoundedShape
  864. //==============================================================================
  865.  
  866. //-------------------------------------------------------------------------
  867. // CBoundedShape::CBoundedShape
  868. //-------------------------------------------------------------------------
  869.  
  870. CBoundedShape::CBoundedShape(unsigned short shapeType) :
  871.     CBaseShape(4, shapeType),
  872.     fRect(0,0,0,0)
  873. {
  874. }
  875.  
  876. //-------------------------------------------------------------------------
  877. // CBoundedShape::~CBoundedShape
  878. //-------------------------------------------------------------------------
  879.  
  880. CBoundedShape::~CBoundedShape()
  881. {
  882. }
  883.  
  884. //-------------------------------------------------------------------------
  885. // CBoundedShape::DrawShape
  886. //-------------------------------------------------------------------------
  887.  
  888. void CBoundedShape::DrawShape(FW_CGraphicContext* gc)
  889. {
  890.     if (HasFillStyle())
  891.     {
  892.         SetShapeProperties(FW_kFilled, GetBrushInk(), GetBrushStyle());
  893.         RenderShape(gc);
  894.     }
  895.     
  896.     if (HasFrameStyle())
  897.     {
  898.         SetShapeProperties(FW_kFramed, GetPenInk(), GetPenStyle());
  899.         RenderShape(gc);
  900.     }
  901.         
  902.     // ----- Remove what I have drawn
  903.     XMPShape* clipShape = ::NewXMPShape();
  904.     gc->GetClipShape(clipShape);
  905.     clipShape->Subtract(GetClipShape(gc));
  906.     gc->SetClipShape(clipShape);
  907.     delete clipShape;
  908. }
  909.  
  910. //-------------------------------------------------------------------------
  911. // CBoundedShape::GetUpdateShape
  912. //-------------------------------------------------------------------------
  913.  
  914. void CBoundedShape::GetUpdateShape(XMPShape* updateShape) const
  915. {
  916.     FW_CRect rect = GetBoundingBox();
  917.     
  918.     if (IsSelected())
  919.         rect.Inset(ff(-2), ff(-2));
  920.     
  921.     updateShape->SetRectangle(&rect);
  922. }
  923.  
  924. //-------------------------------------------------------------------------
  925. // CBoundedShape::GetClipShape
  926. //-------------------------------------------------------------------------
  927.  
  928. XMPShape* CBoundedShape::GetClipShape(FW_CGraphicContext* gc)
  929. {
  930.     if (fClipShape == NULL)
  931.     {
  932.         FW_PlatformRegion rgn = ::NewRgn();
  933.         if (FrameOnly())
  934.         {
  935.             GetDragRgn(gc,rgn);
  936.         }
  937.         else
  938.         {
  939.             FW_CInk ink(FW_kRGBBlack);
  940.             FW_CStyle style(ff(1));
  941.             FW_CRect rect = GetBoundingBox();
  942.             ::OpenRgn();
  943.             OutlineShape(gc, ink, style, rect);
  944.             ::CloseRgn(rgn);
  945.         }
  946.         fClipShape = ::NewXMPShape(rgn);
  947.     }
  948.     
  949.     return fClipShape;
  950. }
  951.  
  952. //-------------------------------------------------------------------------
  953. // CBoundedShape::GetDragRgn
  954. //-------------------------------------------------------------------------
  955.  
  956. void CBoundedShape::GetDragRgn(FW_CGraphicContext* gc, FW_PlatformRegion dragRgn)
  957. {
  958.     FW_CRect rect = GetBoundingBox();
  959.     
  960.     FW_CInk ink(FW_kRGBBlack);
  961.     FW_CStyle style(ff(1));
  962.     
  963.     ::OpenRgn();
  964.     OutlineShape(gc, ink, style, rect);
  965.     ::CloseRgn(dragRgn);
  966.     
  967.     FW_SPlatformPoint penSize = gc->AsPlatformPoint(FW_CPoint(GetPenSize(), GetPenSize()));
  968.  
  969.     FW_PlatformRegion tempRgn = ::NewRgn();
  970.     ::CopyRgn(dragRgn, tempRgn);
  971.     ::InsetRgn(tempRgn, penSize.h, penSize.v);
  972.     ::DiffRgn(dragRgn, tempRgn, dragRgn);
  973.     ::DisposeRgn(tempRgn);
  974. }
  975.  
  976. //-------------------------------------------------------------------------
  977. // CBoundedShape::GetHandleCenter
  978. //-------------------------------------------------------------------------
  979.  
  980. void CBoundedShape::GetHandleCenter(short whichHandle, FW_CPoint* center) const
  981. {
  982.     FW_CRect rect = GetBoundingBox();
  983.  
  984.     switch (whichHandle)
  985.     {
  986.         case kInTopLeftCorner:
  987.             center->x = rect.left;
  988.             center->y = rect.top;
  989.             break;
  990.         case kInTopRightCorner:
  991.             center->x = rect.right-ff(1);
  992.             center->y = rect.top;
  993.             break;
  994.         case kInBottomLeftCorner:
  995.             center->x = rect.left;
  996.             center->y = rect.bottom-ff(1);
  997.             break;
  998.         case kInBottomRightCorner:
  999.             center->x = rect.right-ff(1);
  1000.             center->y = rect.bottom-ff(1);
  1001.             break;
  1002.     }
  1003. }
  1004.  
  1005. //-------------------------------------------------------------------------
  1006. // CBoundedShape::ResizeFeedback
  1007. //-------------------------------------------------------------------------
  1008.  
  1009. void CBoundedShape::ResizeFeedback(FW_CGraphicContext* gc, FW_CInk ink, FW_CStyle style, const FW_CRect& originalRect, const FW_CRect& mapRect)
  1010. {
  1011. FW_UNUSED(originalRect);
  1012.  
  1013.     FW_CRect rect(mapRect);
  1014.     rect.Sort();
  1015.     OutlineShape(gc, ink, style, rect);
  1016. }
  1017.  
  1018. //-------------------------------------------------------------------------
  1019. // CBoundedShape::HitTest
  1020. //-------------------------------------------------------------------------
  1021.  
  1022. FW_Boolean CBoundedShape::HitTest(FW_CGraphicContext* gc, const FW_CPoint& mouse, XMPEventData event) const
  1023. {
  1024. FW_UNUSED(event);
  1025. FW_UNUSED(gc);
  1026.  
  1027.     FW_Boolean result = FALSE;
  1028.     FW_CRect rect = GetBoundingBox();
  1029.     
  1030.     if (HasFillStyle())
  1031.     {
  1032.         result = rect.Contains(mouse);
  1033.     }
  1034.     else
  1035.     {
  1036.         rect.Inset(ff(-2), ff(-2));
  1037.         if (rect.Contains(mouse))
  1038.         {
  1039.             rect.Inset(ff(2) + GetPenSize() + ff(2), ff(2) + GetPenSize() + ff(2));
  1040.             result = !rect.Contains(mouse);
  1041.         }
  1042.     }
  1043.     
  1044.     return result;
  1045. }
  1046.  
  1047. //-------------------------------------------------------------------------
  1048. // CBoundedShape::MapShape
  1049. //-------------------------------------------------------------------------
  1050.  
  1051. void CBoundedShape::MapShape(const FW_CRect& srcRect, const FW_CRect& dstRect)
  1052. {
  1053.     FW_CRect rect = GetBoundingBox();
  1054.  
  1055.     ClearCache();
  1056.  
  1057.     rect.Map(srcRect, dstRect);
  1058.     
  1059.     rect.Sort();
  1060.     
  1061.     XMPCoordinate penSize = GetPenSize();
  1062.     if (rect.right == rect.left)
  1063.         rect.right = rect.left + penSize;
  1064.     if (rect.bottom == rect.top)
  1065.         rect.bottom = rect.top + penSize;
  1066.     
  1067.     SetBoundingBox(rect);
  1068. }
  1069.  
  1070. //-------------------------------------------------------------------------
  1071. // CBoundedShape::OffsetShape
  1072. //-------------------------------------------------------------------------
  1073.  
  1074. void CBoundedShape::OffsetShape(XMPCoordinate xDelta, XMPCoordinate yDelta)
  1075. {
  1076.     ClearCache();
  1077.     FW_CRect rect = GetBoundingBox();
  1078.     rect.Offset(xDelta, yDelta);
  1079.     SetBoundingBox(rect);
  1080. }
  1081.  
  1082. //-------------------------------------------------------------------------
  1083. // CBoundedShape::SetShapeGeometry
  1084. //-------------------------------------------------------------------------
  1085.  
  1086. void CBoundedShape::SetShapeGeometry(const FW_CPoint& anchorPoint,  const FW_CPoint& currentPoint)
  1087. {
  1088.     FW_CRect rect = GetBoundingBox();
  1089.     CalcRect(anchorPoint, currentPoint, &rect);
  1090.     SetBoundingBox(rect);
  1091. }
  1092.  
  1093. //-------------------------------------------------------------------------
  1094. // CBoundedShape::CalcRect
  1095. //-------------------------------------------------------------------------
  1096.  
  1097. void CBoundedShape::CalcRect(const FW_CPoint& anchorPoint, const FW_CPoint& endPoint, FW_CRect* rect)
  1098. {
  1099.     if (anchorPoint.x < endPoint.x)
  1100.     {
  1101.         rect->left = anchorPoint.x;
  1102.         rect->right = endPoint.x;
  1103.     }
  1104.     else
  1105.     {
  1106.         rect->left = endPoint.x;
  1107.         rect->right = anchorPoint.x + ff(XMPASLMQDGlobals.thePort->pnSize.h);
  1108.     }
  1109.     
  1110.     if (anchorPoint.y < endPoint.y)
  1111.     {
  1112.         rect->top = anchorPoint.y;
  1113.         rect->bottom = endPoint.y;
  1114.     }
  1115.     else
  1116.     {
  1117.         rect->top = endPoint.y;
  1118.         rect->bottom = anchorPoint.y + ff(XMPASLMQDGlobals.thePort->pnSize.v);
  1119.     }
  1120. }
  1121.  
  1122. //-------------------------------------------------------------------------
  1123. // CBoundedShape::Flatten
  1124. //-------------------------------------------------------------------------
  1125.  
  1126. void CBoundedShape::Flatten(XMPStorageUnit* storage)
  1127. {    
  1128.     CBaseShape::Flatten(storage);
  1129.     FW_CRect rect = GetBoundingBox();
  1130.     storage->SetValue(sizeof(rect), (XMPValue)&rect);
  1131. }
  1132.  
  1133. //-------------------------------------------------------------------------
  1134. // CBoundedShape::Unflatten
  1135. //-------------------------------------------------------------------------
  1136.  
  1137. void CBoundedShape::Unflatten(CDrawPart* drawPart, XMPStorageUnit* storage)
  1138. {    
  1139.     CBaseShape::Unflatten(drawPart, storage);
  1140.     FW_CRect rect;
  1141.     storage->GetValue(sizeof(rect), (XMPValue)&rect);
  1142.     SetBoundingBox(rect);
  1143. }
  1144.  
  1145. //==============================================================================
  1146. // class CRectShape
  1147. //==============================================================================
  1148.  
  1149. //-------------------------------------------------------------------------
  1150. // CRectShape::CRectShape
  1151. //-------------------------------------------------------------------------
  1152.  
  1153. CRectShape::CRectShape() :
  1154.     CBoundedShape(kRectShape),
  1155.     fShape(FW_kZeroRect)
  1156. {
  1157.     fBaseShape = fShape;
  1158. }
  1159.  
  1160. //-------------------------------------------------------------------------
  1161. // CRectShape::CRectShape
  1162. //-------------------------------------------------------------------------
  1163.  
  1164. CRectShape::CRectShape(unsigned short shapeType) :
  1165.     CBoundedShape(shapeType),
  1166.     fShape(FW_kZeroRect)
  1167. {
  1168.     fBaseShape = fShape;
  1169. }
  1170.  
  1171. //-------------------------------------------------------------------------
  1172. // CRectShape::~CRectShape
  1173. //-------------------------------------------------------------------------
  1174.  
  1175. CRectShape::~CRectShape()
  1176. {
  1177. }
  1178.  
  1179. //-------------------------------------------------------------------------
  1180. // CRectShape::GetBoundingBox
  1181. //-------------------------------------------------------------------------
  1182.  
  1183. FW_CRect CRectShape::GetBoundingBox() const
  1184. {
  1185.     return fShape->GetShapeBounds();
  1186. }
  1187.  
  1188. //-------------------------------------------------------------------------
  1189. // CRectShape::SetBoundingBox
  1190. //-------------------------------------------------------------------------
  1191.  
  1192. void CRectShape::SetBoundingBox(const FW_CRect& bounds)
  1193. {
  1194.     fShape->SetRectangle(bounds);
  1195. }
  1196.     
  1197. //-------------------------------------------------------------------------
  1198. // CRectShape::OutlineShape
  1199. //-------------------------------------------------------------------------
  1200.  
  1201. void CRectShape::OutlineShape(FW_CGraphicContext* gc, FW_CInk ink, FW_CStyle style, const FW_CRect& rect)
  1202. {
  1203.     FW_CRectShape rectShape(rect);
  1204.     rectShape->SetShapeFill(FW_kFramed);
  1205.     rectShape->SetShapeStyle(style);
  1206.     rectShape->SetShapeInk(ink);
  1207.     rectShape->Draw(gc);
  1208. }
  1209.  
  1210. //==============================================================================
  1211. // class COvalShape
  1212. //==============================================================================
  1213.  
  1214. //-------------------------------------------------------------------------
  1215. // COvalShape::COvalShape
  1216. //-------------------------------------------------------------------------
  1217.  
  1218. COvalShape::COvalShape():
  1219.     CBoundedShape(kOvalShape),
  1220.     fShape(FW_kZeroRect)
  1221. {
  1222.     fBaseShape = fShape;
  1223. }
  1224.  
  1225. //-------------------------------------------------------------------------
  1226. // COvalShape::~COvalShape
  1227. //-------------------------------------------------------------------------
  1228.  
  1229. COvalShape::~COvalShape()
  1230. {
  1231. }
  1232.  
  1233. //-------------------------------------------------------------------------
  1234. // COvalShape::GetBoundingBox
  1235. //-------------------------------------------------------------------------
  1236.  
  1237. FW_CRect COvalShape::GetBoundingBox() const
  1238. {
  1239.     return fShape->GetShapeBounds();
  1240. }
  1241.  
  1242. //-------------------------------------------------------------------------
  1243. // COvalShape::SetBoundingBox
  1244. //-------------------------------------------------------------------------
  1245.  
  1246. void COvalShape::SetBoundingBox(const FW_CRect& bounds)
  1247. {
  1248.     fShape->SetRectangle(bounds);
  1249. }
  1250.     
  1251. //-------------------------------------------------------------------------
  1252. // COvalShape::OutlineShape
  1253. //-------------------------------------------------------------------------
  1254.  
  1255. void COvalShape::OutlineShape(FW_CGraphicContext* gc, FW_CInk ink, FW_CStyle style, const FW_CRect& rect)
  1256. {
  1257.     FW_COvalShape ovalShape(rect);
  1258.     ovalShape->SetShapeFill(FW_kFramed);
  1259.     ovalShape->SetShapeStyle(style);
  1260.     ovalShape->SetShapeInk(ink);
  1261.     ovalShape->Draw(gc);
  1262. }
  1263.  
  1264. //-------------------------------------------------------------------------
  1265. // COvalShape::HitTest
  1266. //-------------------------------------------------------------------------
  1267.  
  1268. FW_Boolean COvalShape::HitTest(FW_CGraphicContext* gc, const FW_CPoint& mouse, XMPEventData event) const
  1269. {    
  1270. FW_UNUSED(event);
  1271.  
  1272.     // For now use a region
  1273.     FW_Boolean result = FALSE;
  1274.     
  1275.     FW_CRect rect = GetBoundingBox();
  1276.     FW_SPlatformRect qdRect = gc->AsPlatformRect(rect);
  1277.     
  1278.     ::InsetRect(&qdRect, -2, -2);
  1279.  
  1280.     FW_PlatformRegion rgn = ::NewRgn();
  1281.     ::OpenRgn();
  1282.     ::FrameOval(&qdRect);
  1283.     ::CloseRgn(rgn);
  1284.     
  1285.     FW_SPlatformPoint qdMouse = mouse;
  1286.     if (::PtInRgn(qdMouse, rgn))
  1287.     {
  1288.         if (!HasFillStyle())
  1289.         {
  1290.             FW_SPlatformRect qdRect2 = qdRect;
  1291.             ::InsetRect(&qdRect2, 2 + FixedToInt(GetPenSize()) + 2, 2 + FixedToInt(GetPenSize()) + 2);            
  1292.             ::MapRgn(rgn, &qdRect, &qdRect2);
  1293.             result = !::PtInRgn(qdMouse, rgn);
  1294.         }
  1295.         result = TRUE; 
  1296.     }
  1297.         
  1298.     DisposeRgn(rgn);
  1299.     
  1300.     return result;
  1301. }
  1302.  
  1303. //=========================================================================
  1304. // class CRoundRectShape
  1305. //=========================================================================
  1306.  
  1307. //-------------------------------------------------------------------------
  1308. // CRoundRectShape::CRoundRectShape
  1309. //-------------------------------------------------------------------------
  1310.  
  1311. CRoundRectShape::CRoundRectShape():
  1312.     CBoundedShape(kRRectShape),
  1313.     fShape(FW_kZeroRect, FW_kZeroPoint)
  1314. {
  1315.     fBaseShape = fShape;
  1316. }
  1317.  
  1318. //-------------------------------------------------------------------------
  1319. // CRoundRectShape::~CRoundRectShape
  1320. //-------------------------------------------------------------------------
  1321.  
  1322. CRoundRectShape::~CRoundRectShape()
  1323. {
  1324. }
  1325.  
  1326. //-------------------------------------------------------------------------
  1327. // CRoundRectShape::OutlineShape
  1328. //-------------------------------------------------------------------------
  1329.  
  1330. void CRoundRectShape::OutlineShape(FW_CGraphicContext* gc, FW_CInk ink, FW_CStyle style, const FW_CRect& rect)
  1331. {
  1332.     FW_CRoundRectShape roundRecShape(rect, fShape->GetOvalSize());
  1333.     roundRecShape->SetShapeFill(FW_kFramed);
  1334.     roundRecShape->SetShapeStyle(style);
  1335.     roundRecShape->SetShapeInk(ink);
  1336.     roundRecShape->Draw(gc);
  1337. }
  1338.  
  1339. //-------------------------------------------------------------------------
  1340. // CRoundRectShape::GetBoundingBox
  1341. //-------------------------------------------------------------------------
  1342.  
  1343. FW_CRect CRoundRectShape::GetBoundingBox() const
  1344. {
  1345.     return fShape->GetShapeBounds();
  1346. }
  1347.  
  1348. //-------------------------------------------------------------------------
  1349. // CRoundRectShape::SetBoundingBox
  1350. //-------------------------------------------------------------------------
  1351.  
  1352. void CRoundRectShape::SetBoundingBox(const FW_CRect& bounds)
  1353. {
  1354.     fShape->SetRectangle(bounds);
  1355. }
  1356.     
  1357. //-------------------------------------------------------------------------
  1358. // CRoundRectShape::SetShapeGeometry
  1359. //-------------------------------------------------------------------------
  1360.  
  1361. void CRoundRectShape::SetShapeGeometry(const FW_CPoint& anchorPoint,  const FW_CPoint& currentPoint)
  1362. {
  1363.     CBoundedShape::SetShapeGeometry(anchorPoint, currentPoint);
  1364.     fShape->SetOvalSize(FW_CPoint(ff(32), ff(32)));
  1365. }
  1366.  
  1367. //=========================================================================
  1368. // class CProxyShape
  1369. //=========================================================================
  1370.  
  1371. //-------------------------------------------------------------------------
  1372. // CProxyShape::CProxyShape
  1373. //-------------------------------------------------------------------------
  1374.  
  1375. CProxyShape::CProxyShape(const FW_CRect& rect):
  1376.     CRectShape(kProxyShape)
  1377. {
  1378.     fFrozen = FALSE;
  1379.  
  1380.     SetBoundingBox(rect);
  1381.         
  1382.     fProxyRun = NULL;
  1383.     
  1384.     FW_CStyle style(ff(1));
  1385.     SetPenStyle(style);
  1386. }
  1387.  
  1388. //-------------------------------------------------------------------------
  1389. // CProxyShape::CProxyShape
  1390. //-------------------------------------------------------------------------
  1391.  
  1392. CProxyShape::CProxyShape():
  1393.     CRectShape(kProxyShape)
  1394. {
  1395.     fProxyRun = NULL;
  1396.     fFrozen = FALSE;
  1397.     
  1398.     FW_CStyle style(ff(1));
  1399.     SetPenStyle(style);
  1400. }
  1401.  
  1402. //-------------------------------------------------------------------------
  1403. // CProxyShape::~CProxyShape
  1404. //-------------------------------------------------------------------------
  1405.  
  1406. CProxyShape::~CProxyShape()
  1407. {
  1408. }
  1409.     
  1410. //-------------------------------------------------------------------------
  1411. // CProxyShape::Removed
  1412. //-------------------------------------------------------------------------
  1413.  
  1414. void CProxyShape::Removed()
  1415. {
  1416.     CRectShape::Removed();
  1417.     
  1418.     fProxyRun->GetEmbeddingPart()->RemoveEmbeddedFrames(fProxyRun);
  1419. }
  1420.  
  1421. //-------------------------------------------------------------------------
  1422. // CProxyShape::DrawShape
  1423. //
  1424. //    Because there can be multiple of CProxyShape pointing on an embedded
  1425. //    frame, I only draw those belonging to this frame.
  1426. //-------------------------------------------------------------------------
  1427.  
  1428. void CProxyShape::DrawShape(FW_CGraphicContext* gc)
  1429. {
  1430.     XMPShape *clipShape = ::NewXMPShape();
  1431.     gc->GetClipShape(clipShape);
  1432.     
  1433.     XMPShape* tempShape = ::NewXMPShape();
  1434.     
  1435.     FW_CFacet* theFacet = FW_CFacet::XMPtoFWFacet(gc->GetXMPFacet());
  1436.     
  1437.     FW_CEmbeddedXMPFacetsIterator ite(fProxyRun,theFacet, kXMPFrontToBack);
  1438.     for (XMPFacet *embeddedXMPFacet = ite.First(); ite.IsNotComplete(); embeddedXMPFacet = ite.Next())
  1439.     {    
  1440.         tempShape->CopyFrom(clipShape);
  1441.         tempShape->Transform(theFacet->GetFrameTransform());    // Frame -> Window
  1442.         tempShape->InverseTransform(embeddedXMPFacet->GetFrameTransform());     // Window -> Frame
  1443.  
  1444.         embeddedXMPFacet->Draw(tempShape);
  1445.         embeddedXMPFacet->DrawChildren(tempShape);
  1446.         
  1447.         tempShape->CopyFrom(embeddedXMPFacet->GetClipShape());
  1448.         tempShape->Transform(embeddedXMPFacet->GetExternalTransform());
  1449.         clipShape->Subtract(tempShape);
  1450.     }
  1451.     
  1452.     delete tempShape;
  1453.  
  1454.     gc->SyncGraphicContext(clipShape);
  1455.     delete clipShape;
  1456. }
  1457.  
  1458.  
  1459. //-------------------------------------------------------------------------
  1460. // CProxyShape::HitTest
  1461. //-------------------------------------------------------------------------
  1462.  
  1463. FW_Boolean CProxyShape::HitTest(FW_CGraphicContext* gc, const FW_CPoint& mouse, XMPEventData event) const
  1464. {
  1465. FW_UNUSED(event);
  1466.     FW_CFacet* facet = FW_CFacet::XMPtoFWFacet(gc->GetXMPFacet());
  1467.     FW_CPoint point = facet->GetWindowContentTransform()->TransformPoint(mouse);
  1468.     return fProxyRun->WhichEmbeddedFacet(facet, point) != NULL;
  1469. }
  1470.  
  1471. //-------------------------------------------------------------------------
  1472. // CProxyShape::MapShape
  1473. //-------------------------------------------------------------------------
  1474.  
  1475. void CProxyShape::MapShape(const FW_CRect& srcRect, const FW_CRect& dstRect)
  1476. {
  1477.     CRectShape::MapShape(srcRect, dstRect);
  1478.  
  1479.     XMPShape *shape = ::NewXMPShape(GetBoundingBox());
  1480.     
  1481.     fProxyRun->ResizeProxyFrames(shape);        // shape is kept by the frame
  1482. }
  1483.  
  1484. //-------------------------------------------------------------------------
  1485. // CProxyShape::OffsetShape
  1486. //-------------------------------------------------------------------------
  1487.  
  1488. void CProxyShape::OffsetShape(XMPCoordinate xDelta, XMPCoordinate yDelta)
  1489. {    
  1490.     CRectShape::OffsetShape(xDelta, yDelta);
  1491.  
  1492.     FW_CPoint offset(xDelta, yDelta);
  1493.     
  1494.     fProxyRun->OffsetProxyFrames(offset);
  1495. }
  1496.         
  1497. //-------------------------------------------------------------------------
  1498. // CProxyShape::SelectShape
  1499. //-------------------------------------------------------------------------
  1500.  
  1501. void CProxyShape::SelectShape(FW_Boolean state)
  1502. {
  1503.     CBaseShape::SelectShape(state);
  1504.     fProxyRun->SetSelectState(state);
  1505. }
  1506.  
  1507. //-------------------------------------------------------------------------
  1508. // CProxyShape::Flatten
  1509. //-------------------------------------------------------------------------
  1510.  
  1511. void CProxyShape::Flatten(XMPStorageUnit* storage)
  1512. {    
  1513.     CRectShape::Flatten(storage);
  1514.  
  1515.     fProxyRun->Externalize(storage);
  1516. }
  1517.  
  1518. //-------------------------------------------------------------------------
  1519. // CProxyShape::Unflatten
  1520. //-------------------------------------------------------------------------
  1521.  
  1522. void CProxyShape::Unflatten(CDrawPart* drawPart, XMPStorageUnit* storage)
  1523. {    
  1524.     CRectShape::Unflatten(drawPart, storage);
  1525.         
  1526.     fProxyRun = (CDrawProxyRun*)drawPart->NewProxyRun();
  1527.     fProxyRun->Internalize(storage);
  1528.     fProxyRun->SetShape(this);
  1529. }
  1530.  
  1531. //-------------------------------------------------------------------------
  1532. // CProxyShape::CloneTo
  1533. //-------------------------------------------------------------------------
  1534.  
  1535. void CProxyShape::CloneTo(XMPStorageUnit* storageUnit, FW_CFrame* commandFrame, XMPCloneKind cloneKind)
  1536. {
  1537.     // I can't call CRectShape::CloneTo because it will call CProxyShape::Flatten
  1538.     CRectShape::Flatten(storageUnit);
  1539.     fProxyRun->CloneTo(storageUnit, commandFrame, cloneKind);
  1540. }
  1541.  
  1542. //-------------------------------------------------------------------------
  1543. // CProxyShape::CloneFrom
  1544. //-------------------------------------------------------------------------
  1545.  
  1546. void CProxyShape::CloneFrom(CDrawPart* drawPart, XMPStorageUnit* storageUnit, XMPCloneKind cloneKind)
  1547. {
  1548.     // I can't call CRectShape::CloneFrom because it will call CProxyShape::Unflatten
  1549.     CRectShape::Unflatten(drawPart, storageUnit);
  1550.     
  1551.     CDrawProxyRun* proxyRun = (CDrawProxyRun*)drawPart->NewProxyRun();
  1552.     
  1553.     // ----- Set the proxyRun of the shape and the shape of the proxyRun -----
  1554.     SetProxyRun(proxyRun);
  1555.     proxyRun->SetShape(this);
  1556.  
  1557.     // ----- Clone the proxyRun -----
  1558.     XMPFrame* embeddedXMPFrame = proxyRun->CloneFrom(storageUnit, cloneKind);
  1559.     
  1560.     // ----- Embed the frame -----
  1561.     FW_CRect box = GetBoundingBox();
  1562.     FW_CPoint ptTemp(box.left, box.top);
  1563.     XMPTransform* externalXForm = ::NewXMPTransform(ptTemp);
  1564.  
  1565.     drawPart->EmbedFrame(embeddedXMPFrame, 
  1566.                          proxyRun,
  1567.                          drawPart->GetMainPresentation(), 
  1568.                            externalXForm,
  1569.                          FALSE);
  1570. }
  1571.  
  1572. //-------------------------------------------------------------------------
  1573. // CProxyShape::ProxyShapeChanged
  1574. //-------------------------------------------------------------------------
  1575.  
  1576. void CProxyShape::ProxyShapeChanged(const FW_CRect& rect)
  1577. {
  1578.     SetBoundingBox(rect);
  1579. }
  1580.  
  1581. //-------------------------------------------------------------------------
  1582. // CProxyShape::MovedAfter
  1583. //
  1584. //    shape has been moved after this
  1585. //-------------------------------------------------------------------------
  1586.  
  1587. void CProxyShape::MovedAfter(CBaseShape* shape)
  1588. {
  1589.     if (shape->GetShapeType() == kProxyShape)
  1590.     {
  1591.         ((CProxyShape*)shape)->GetProxyRun()->MoveBehind(GetProxyRun());
  1592.     }
  1593. }
  1594.  
  1595. //-------------------------------------------------------------------------
  1596. // CProxyShape::MovedBefore
  1597. //
  1598. //    shape has been moved before this
  1599. //-------------------------------------------------------------------------
  1600.  
  1601. void CProxyShape::MovedBefore(CBaseShape* shape)
  1602. {
  1603.     if (shape->GetShapeType() == kProxyShape)
  1604.     {
  1605.         ((CProxyShape*)shape)->GetProxyRun()->MoveBefore(GetProxyRun());
  1606.     }
  1607. }
  1608.  
  1609. //-------------------------------------------------------------------------
  1610. // CProxyShape::MovedFirst
  1611. //
  1612. //    this has been moved First
  1613. //-------------------------------------------------------------------------
  1614.  
  1615. void CProxyShape::MovedFirst()
  1616. {
  1617.     GetProxyRun()->MoveFirst();
  1618. }
  1619.  
  1620. //-------------------------------------------------------------------------
  1621. // CProxyShape::MovedLast
  1622. //
  1623. //    this has been moved Last
  1624. //-------------------------------------------------------------------------
  1625.  
  1626. void CProxyShape::MovedLast()
  1627. {
  1628.     GetProxyRun()->MoveLast();
  1629. }
  1630.  
  1631. //-------------------------------------------------------------------------
  1632. // CProxyShape::SetFrozen
  1633. //-------------------------------------------------------------------------
  1634.  
  1635. FW_Boolean CProxyShape::SetFrozen(FW_Boolean state)
  1636. {
  1637.     if (fFrozen != state)
  1638.     {
  1639.         fFrozen = state;    
  1640.         return TRUE;
  1641.     }
  1642.     
  1643.     return FALSE;
  1644. }
  1645.  
  1646. //-------------------------------------------------------------------------
  1647. // CProxyShape::IsFrozen
  1648. //-------------------------------------------------------------------------
  1649.  
  1650. FW_Boolean CProxyShape::IsFrozen() const
  1651. {
  1652.     return fFrozen;
  1653. }
  1654.